/*
 * bsp.c
 *
 * Copyright (C) 2011 - Dr.NP
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * @version bsp.c 1.0.0
 " @package bsp
 * @author Dr.NP <np@bsgroup.org>
 * @update 03/17/2011
 */

/**
 * Main file of bsp server
 *
 * === CHANGELOG ===
 * [03/17/2011] - Creation
 */

#include "bsp.h"

#include "bsp_core.h"
#include "bsp_status.h"
#include "bsp_app.h"
#include "bsp_db_mysql.h"

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void bsp_shutdown(int sig)
{
    fprintf(stderr, "\nBSP server terminated!\nSee you later!\n");
    
    exit(RTN_SUCCESS);
    
    return;
}

int main(int argc, char **argv)
{
    int c;
    char *conf_file = DEFAULT_CONF_FILE;
    char *server_mode_arg = NULL;
    int server_mode = SERVER_MODE_UNITED;

    while ((c = getopt(argc, argv, "c:m:")) != -1)
    {
        switch (c)
        {
            case 'c' : 
                conf_file = strdup(optarg);
                break;

            case 'm' : 
                if (server_mode_arg)
                {
                    free(server_mode_arg);
                }

                server_mode_arg = strdup(optarg);
                break;
                
            default : 
                break;
        }
    }
    
    fprintf(stderr, "\nStarting %s ...\n\n", BSP_VERSION);
    
    chdir(get_dir());
    int res = core_init(conf_file);

    if (RTN_SUCCESS == res)
    {
        chdir(conf_get("APP_BASEDIR"));
        conf_set("SERVER_MODE", DEFAULT_SERVER_MODE, CONF_LEVEL_INIT);
        if (server_mode)
        {
            conf_set("SERVER_MODE", server_mode_arg, CONF_LEVEL_OVERWRITE);
        }

        if (0 == strncasecmp(conf_get("SERVER_MODE"), "center", 6))
        {
            // A center node
            server_mode = SERVER_MODE_CENTER;
            conf_set("SERVER_MODE", "center", CONF_LEVEL_OVERWRITE);
        }

        else if (0 == strncasecmp(conf_get("SERVER_MODE"), "node", 4))
        {
            // A worker node
            server_mode = SERVER_MODE_NODE;
            conf_set("SERVER_MODE", "node", CONF_LEVEL_OVERWRITE);
        }

        else
        {
            // United mode(center+node)
            conf_set("SERVER_MODE", "united", CONF_LEVEL_OVERWRITE);
        }

        // Default db params
        conf_set("MYSQL_HOST", DEFAULT_MYSQL_HOST, CONF_LEVEL_INIT);
        conf_set("MYSQL_DB", DEFAULT_MYSQL_DB, CONF_LEVEL_INIT);
        conf_set("MYSQL_USER", DEFAULT_MYSQL_USER, CONF_LEVEL_INIT);
        conf_set("MYSQL_PASS", DEFAULT_MYSQL_PASS, CONF_LEVEL_INIT);

        db_mysql_init();

        if (server_mode == SERVER_MODE_UNITED || server_mode == SERVER_MODE_CENTER)
        {
            // Initial db
            int mysql_conn_id = db_mysql_connect(
                                                 conf_get("MYSQL_HOST"), 
                                                 conf_get("MYSQL_USER"), 
                                                 conf_get("MYSQL_PASS"), 
                                                 conf_get("MYSQL_DB"), 
                                                 256);
        }

        if (server_mode == SERVER_MODE_UNITED || server_mode == SERVER_MODE_NODE)
        {
            // Load app list
        }
        
        //conf_set("APPDEF_SCRIPT", "etc/app.lua", CONF_LEVEL_INIT);
        //app_init(conf_get("APPDEF_SCRIPT"));
        
        // Object test
/*
        struct object_t *obj = new_object();
        struct kv_t *item = NULL;
        int i;
        char tkey[64];

        for (i = 1; i <= 100000; i ++)
        {
            sprintf(tkey, "%d", i);
            item = alloc_item(tkey, -1);
            set_string_item(item, "Hello World", -1);
            insert_item(obj, item);
        }

        item = alloc_item("a100a", -1);
        set_long_item(item, 100);
        insert_item(obj, item);
        
        item = alloc_item("100a", -1);
        set_long_item(item, 100);
        insert_item(obj, item);
        
        item = alloc_item("200");
        set_long_item(item, 100);
        insert_item(obj, item);
        
        item = alloc_item("8");
        set_string_item(item, "Hello World", -1);
        insert_item(obj, item);
        
        item = alloc_item("7");
        set_bool_item(item, BSP_TRUE);
        insert_item(obj, item);
        
        item = alloc_item("9");
        set_double_item(item, 3.14f);
        insert_item(obj, item);
        
        item = alloc_item("5");
        set_null_item(item);
        insert_item(obj, item);
        
        item = alloc_item("40");
        set_string_item(item, "I love you", -1);
        insert_item(obj, item);

        item = alloc_item("x200");
        set_long_item(item, 100);
        insert_item(obj, item);
        
        item = alloc_item("x8");
        set_string_item(item, "Hello World", -1);
        insert_item(obj, item);
        
        item = alloc_item("200");
        set_bool_item(item, BSP_TRUE);
        insert_item(obj, item);
        
        item = alloc_item("0");
        set_double_item(item, 3.14f);
        insert_item(obj, item);
        
        item = alloc_item("00");
        set_null_item(item);
        insert_item(obj, item);
        
        item = alloc_item("00a");
        set_string_item(item, "I love you", -1);
        insert_item(obj, item);

        struct abuff_t *a = new_abuff();
        dump_object(obj, a);
        printf("%s", a->buff);

        fprintf(stderr, "\nSorting...\n\n");
        sort_object(obj);
        
        fprintf(stderr, "Array done!\n");
*/
        //core_loop(bsp_shutdown);
    }
    
    return res;
}
